package com.leadingsoft.pwxk.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.leadingsoft.common.dto.TableResultDto;
import com.leadingsoft.pwxk.common.PagingPlugin;
import com.leadingsoft.pwxk.common.PagingPluginAssist;
import com.leadingsoft.pwxk.dto.SearchDto;
import com.leadingsoft.pwxk.enums.EDrainCountType;
import com.leadingsoft.pwxk.model.AirPollutionOrg;
import com.leadingsoft.pwxk.model.DrainInfoAirOrgCountOne;
import com.leadingsoft.pwxk.model.DrainInfoAirOrgCountThr;
import com.leadingsoft.pwxk.model.DrainInfoAirOrgCountTwo;
import com.leadingsoft.pwxk.model.DrainInfoWaterApplyCountOne;
import com.leadingsoft.pwxk.model.DrainInfoWaterApplyCountTwo;
import com.leadingsoft.pwxk.model.DrainInfoWaterApplyThr;
import com.leadingsoft.pwxk.model.DrainInfoWaterApplyTwo;
import com.leadingsoft.pwxk.model.QAirPollution;
import com.leadingsoft.pwxk.model.QAirPollutionOrg;
import com.leadingsoft.pwxk.model.QBaseInfo;
import com.leadingsoft.pwxk.model.QDrainBaseInfo;
import com.leadingsoft.pwxk.model.QLatestData;
import com.leadingsoft.pwxk.model.QPwBaseInfo;
import com.leadingsoft.pwxk.model.QWaterDrainApply;
import com.leadingsoft.pwxk.model.QWaterDrainBaseInfoOne;
import com.leadingsoft.pwxk.model.QWaterDrainBaseInfoThr;
import com.leadingsoft.pwxk.model.QWaterDrainBaseInfoTwo;
import com.leadingsoft.pwxk.model.WaterDrainApply;
import com.leadingsoft.pwxk.service.AirPollutionOrgService;
import com.leadingsoft.pwxk.service.DrainCountService;
import com.leadingsoft.pwxk.service.WaterDrainApplyService;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.jpa.impl.JPAQuery;

@Service
public class DrainCountServiceImpl implements DrainCountService {

	@Autowired
	AirPollutionOrgService airPollutionOrgService;
	@Autowired
	WaterDrainApplyService waterDrainApplyService;

	@Autowired
	EntityManager em;
	// 排污单位
	QPwBaseInfo qPwBaseInfo = QPwBaseInfo.pwBaseInfo;
	QBaseInfo qBaseInfo = QBaseInfo.baseInfo;
	QWaterDrainApply qWaterDrainApply = QWaterDrainApply.waterDrainApply;
	QAirPollutionOrg qAirPollutionOrg = QAirPollutionOrg.airPollutionOrg;
	com.leadingsoft.pwxk.model.QLicenseInfo QLicenseInfo = com.leadingsoft.pwxk.model.QLicenseInfo.licenseInfo;

	QLatestData qLatestData = QLatestData.latestData;

	/**
	 * 大气污染物排放口统计通用方法
	 * 
	 * @param searchDto
	 * @param num
	 *            <p>
	 *            flag=true 1：大气主要排放口 ， 2：大气一般排放口 ，3： 大气合计排放
	 *            </p>
	 *            <p>
	 *            flag=false 1：水主要排放口 ， 2：水一般排放口 ，3： 车间或设施排放 ， 4：水排放合计
	 *            </p>
	 * @param flag
	 *            true = 大气统计 / false 水统计
	 * @return
	 */
	private Map<String, Float> countUtil(SearchDto searchDto, int num, boolean flag) {
		JPAQuery<Tuple> query = new JPAQuery<>(em);
		query = query(searchDto, flag, query);

		List<Tuple> fetch = query.fetch();
		// 默认查询当前年
		Integer year = getYear(searchDto);

		List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
		// 统计table - 填充数据
		putData(year, mapList, fetch, num, flag);
		Map<String, Float> countData = countData(mapList);

		// 回收
		mapList = null;
		query = null;
		year = null;
		fetch = null;
		return countData;
	}

	private Integer getYear(SearchDto searchDto) {
		Integer year = Calendar.getInstance().get(Calendar.YEAR);
		if (searchDto != null && StringUtils.isNotBlank(searchDto.getYear())) {
			year = Integer.parseInt(searchDto.getYear());
		}
		return year;
	}

	/**
	 * 大气污染物排放口表格统计通用方法
	 * 
	 * @param searchDto
	 * @param num
	 *            <p>
	 *            flag=true 1：大气主要排放口 ， 2：大气一般排放口 ，3： 大气合计排放
	 *            </p>
	 *            <p>
	 *            flag=false 1：水主要排放口 ， 2：水一般排放口 ，3： 车间或设施排放 ， 4：水排放合计
	 *            </p>
	 * @param flag
	 *            true = 大气统计 / false 水统计
	 * @return
	 */
	public TableResultDto<Map<String, Object>> countTableUtil(SearchDto searchDto, int num, boolean flag, Long draw) {

		JPAQuery<Tuple> query = new JPAQuery<>(em);
		query = query(searchDto, flag, query);
		// 默认查询当前年
		Integer year = getYear(searchDto);
		if (draw == null) {
			searchDto.setSize(Integer.MAX_VALUE);
		}
		@SuppressWarnings("rawtypes")
		OrderSpecifier[] orderSpecifier = { QLicenseInfo.fztime.desc() };
		PagingPluginAssist pagingInfo = PagingPlugin.getPagingInfo(query, searchDto, orderSpecifier);
		List<Tuple> fetch = pagingInfo.getList();

		List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
		// 统计table - 填充数据
		putData(year, mapList, fetch, num, flag);
		FormatData(mapList);
		TableResultDto<Map<String, Object>> tableResultdto = new TableResultDto<Map<String, Object>>();
		tableResultdto.setSuccess(true);
		tableResultdto.setData(mapList);
		tableResultdto.setRecordsTotal(pagingInfo.getRecordsTotal());
		tableResultdto.setDraw(draw);
		year = null;
		query = null;
		pagingInfo = null;
		return tableResultdto;
	}

	private void FormatData(List<Map<String, Object>> mapList) {
		ArrayList<String> keys = new ArrayList<String>();
		keys.addAll(new ArrayList<>(DrainCountService.AIRCOUNTKEYS));
		keys.addAll(new ArrayList<>(DrainCountService.WATERCOUNTKEYS));
		for (Map<String, Object> map : mapList) {
			map.remove("data");
			map.forEach((key, value) -> {
				if (keys.contains(key) && String.valueOf(value).equals("0")) {
					map.put(key, "/");
				}
			});
		}
	}

	private JPAQuery<Tuple> query(SearchDto searchDto, boolean flag, JPAQuery<Tuple> query) {
		if (flag) {
			query = airBaseQuery(searchDto, query);
		} else {
			query = waterBaseQuery(searchDto, query);
		}
		return query;
	}

	/**
	 * 大气统计 基本query
	 * 
	 * @param searchDto
	 * @param query
	 * @return
	 */
	private JPAQuery<Tuple> airBaseQuery(SearchDto searchDto, JPAQuery<Tuple> query) {
		query.select(qBaseInfo.name_region, qBaseInfo.entername, qBaseInfo.tradesname, QLicenseInfo.fztime,
				qAirPollutionOrg.id, qPwBaseInfo.dataid).from(qLatestData).leftJoin(qAirPollutionOrg)
				.on(qLatestData.dataid.eq(qAirPollutionOrg.dataid)).leftJoin(qPwBaseInfo)
				.on(qAirPollutionOrg.dataid.eq(qPwBaseInfo.dataid)).leftJoin(qBaseInfo)
				.on(qPwBaseInfo.enterid.eq(qBaseInfo.enterid)).leftJoin(QLicenseInfo)
				.on(QLicenseInfo.dataid.eq(qAirPollutionOrg.dataid));

		QueryUtil(searchDto, query);
		return query;
	}

	private void QueryUtil(SearchDto searchDto, JPAQuery<Tuple> query) {
		// 条件构建
		where(searchDto, query);
		// 默认查询当前年
		// Integer year = getYear(searchDto);
		/*
		 * query.where(QLicenseInfo.fztime.substring(0,
		 * 4).lt(String.valueOf(year)) .and(QLicenseInfo.fztime.substring(0,
		 * 4).goe(String.valueOf(year - 5))));
		 */
	}

	private JPAQuery<Tuple> waterBaseQuery(SearchDto searchDto, JPAQuery<Tuple> query) {
		query.select(qBaseInfo.name_region, qBaseInfo.entername, qBaseInfo.tradesname, QLicenseInfo.fztime,
				qWaterDrainApply.id, qPwBaseInfo.dataid).from(qLatestData).leftJoin(qWaterDrainApply)
				.on(qLatestData.dataid.eq(qWaterDrainApply.dataid)).leftJoin(qPwBaseInfo)
				.on(qWaterDrainApply.dataid.eq(qPwBaseInfo.dataid)).leftJoin(qBaseInfo)
				.on(qPwBaseInfo.enterid.eq(qBaseInfo.enterid)).leftJoin(QLicenseInfo)
				.on(QLicenseInfo.dataid.eq(qWaterDrainApply.dataid));
		QueryUtil(searchDto, query);
		return query;
	}

	private Map<String, Float> countData(List<Map<String, Object>> mapList) {
		Map<String, Float> mapCount = new HashMap<String, Float>();
		for (Map<String, Object> map : mapList) {
			@SuppressWarnings("unchecked")
			Map<String, Object> data = (Map<String, Object>) map.get("data");
			for (String key : data.keySet()) {
				Float countValue = mapCount.containsKey(key) ? mapCount.get(key) : 0f;
				Float dataValue = String.valueOf(data.get(key)).contains("/") ? 0f
						: Float.valueOf(String.valueOf(data.get(key)));
				mapCount.put(key, countValue + dataValue);
			}
		}
		return mapCount;
	}

	private void where(SearchDto searchDto, JPAQuery<Tuple> query) {
		if (searchDto != null) {
			if (StringUtils.isNotBlank(searchDto.getDevcompany())) {
				query.where(qBaseInfo.entername.contains(searchDto.getDevcompany()));
			}
			if (StringUtils.isNotBlank(searchDto.getHyid())) {
				query.where(qBaseInfo.code_trade.eq(searchDto.getHyid()));
			}
			if (null != searchDto.getHyids() && searchDto.getHyids().length > 0) {
				query.where(qBaseInfo.code_trade.in(searchDto.getHyids()));
			}
			if (StringUtils.isNotBlank(searchDto.getCodeRegion())) {
				query.where(qBaseInfo.code_region.eq(searchDto.getCodeRegion()));
			}
		}
	}

	/**
	 * 填充数据
	 * 
	 * @param year
	 *            筛选年份
	 * @param mapList
	 *            数据容器
	 * @param fetch
	 *            抓取数据结果集
	 * @param num
	 *            <p>
	 *            flag=true 1：大气主要排放口 ， 2：大气一般排放口 ，3： 大气合计排放
	 *            </p>
	 *            <p>
	 *            flag=false 1：水主要排放口 ， 2：水一般排放口 ，3： 车间或设施排放 ， 4：水排放合计
	 *            </p>
	 * @param flag
	 *            true = 大气统计 / false 水统计
	 */
	private void putData(Integer year, List<Map<String, Object>> mapList, List<Tuple> fetch, int num, Boolean flag) {
		// 构建外层数据结构
		for (Tuple row : fetch) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("year", year);
			map.put("name_region", row.get(qBaseInfo.name_region));
			map.put("entername", row.get(qBaseInfo.entername));
			map.put("tradesname", row.get(qBaseInfo.tradesname));
			map.put("fztime", row.get(QLicenseInfo.fztime));
			map.put("dataid", row.get(qPwBaseInfo.dataid));
			if (flag) {
				Map<String, Object> data = putAirDataByYear(num, year, map,
						airPollutionOrgService.findById(row.get(qAirPollutionOrg.id)));
				for (String key : AIRCOUNTKEYS) {
					map.put(key, data.containsKey(key) ? data.get(key) : 0);
				}
				map.put("data", data);
			} else {
				Map<String, Object> data = putWaterDataByYear(num, year, map,
						waterDrainApplyService.findById(row.get(qWaterDrainApply.id)));
				map.put("data", data);
				for (String key : WATERCOUNTKEYS) {
					map.put(key, data.containsKey(key) ? data.get(key) : 0);
				}
			}
			mapList.add(map);
		}
	}

	// 提取企业大气排放物及排放量
	Map<String, Object> putAirDataByYear(int num, Integer year, Map<String, Object> map,
			AirPollutionOrg airPollutionOrg) {
		Map<String, Object> data = new HashMap<String, Object>();
		String fztimeString = (String) map.get("fztime");
		Integer fztimeYear = Integer.valueOf(fztimeString.substring(0, 4));
		switch (num) {
		case 1:// 大气主要排放口合计
			List<DrainInfoAirOrgCountOne> countOneList = airPollutionOrg.getCountOneList();
			for (DrainInfoAirOrgCountOne countOne : countOneList) {
				float value = absCount(year, fztimeYear, countOne);
				data.put(countOne.getAirwrwname(), -1f == value ? "/" : String.valueOf(value));
			}
			break;
		case 2:// 大气一般排放口合计
			List<DrainInfoAirOrgCountTwo> countTwoList = airPollutionOrg.getCountTwoList();
			for (DrainInfoAirOrgCountTwo countTwo : countTwoList) {
				float value = absCount(year, fztimeYear, countTwo);
				data.put(countTwo.getAirwrwname(), -1f == value ? "/" : String.valueOf(value));
			}
			break;
		case 3:// 大气排放口合计
			List<DrainInfoAirOrgCountThr> countThrList = airPollutionOrg.getCountThrList();
			for (DrainInfoAirOrgCountThr countThr : countThrList) {
				float value = absCount(year, fztimeYear, countThr);
				data.put(countThr.getAirwrwname(), -1f == value ? "/" : String.valueOf(value));
			}
			break;
		default:
			break;
		}
		fztimeYear = null;
		return data;
	}

	// 提取企业水排放物及排放量
	Map<String, Object> putWaterDataByYear(int num, Integer year, Map<String, Object> map, WaterDrainApply model) {
		Map<String, Object> data = new HashMap<String, Object>();
		String fztimeString = (String) map.get("fztime");
		Integer fztimeYear = Integer.valueOf(fztimeString.substring(0, 4));

		switch (num) {
		case 1:// 水主要排放口合计
			List<DrainInfoWaterApplyCountOne> countOneList = model.getOneCountList();
			for (DrainInfoWaterApplyCountOne countOne : countOneList) {
				float value = absCount(year, fztimeYear, countOne);
				data.put(countOne.getWaterwrwname(), -1f == value ? "/" : String.valueOf(value));
			}
			break;
		case 2:// 水一般排放口合计
			List<DrainInfoWaterApplyTwo> TwoList = model.getTwoList();
			for (DrainInfoWaterApplyTwo countTwo : TwoList) {
				float value = absCount(year, fztimeYear, countTwo);
				data.put(countTwo.getWrwname(), -1f == value ? "/" : String.valueOf(value));
			}
			break;
		case 3:// 设施或车间废水排放口合计
			List<DrainInfoWaterApplyThr> ThrList = model.getThrList();
			for (DrainInfoWaterApplyThr countThr : ThrList) {
				float value = absCount(year, fztimeYear, countThr);
				data.put(countThr.getWrwname(), -1f == value ? "/" : String.valueOf(value));
			}
			break;
		case 4:// 全厂排放口合计
			List<DrainInfoWaterApplyCountTwo> countThrList = model.getTwoConutList();
			for (DrainInfoWaterApplyCountTwo countThr : countThrList) {
				float value = absCount(year, fztimeYear, countThr);
				data.put(countThr.getWaterwrwname(), -1f == value ? "/" : String.valueOf(value));
			}
			break;
		default:
			break;
		}
		fztimeYear = null;
		return data;
	}

	// 安年份取值 -1.0 -> 无值
	private float absCount(Integer year, Integer fztimeYear, Object Obj) {
		JSONObject jsonStr = (JSONObject) JSON.toJSON(Obj);
		@SuppressWarnings("unchecked")
		Map<String, String> mapStr = (Map<String, String>) JSON.parse(jsonStr.toJSONString());
		return count(year, fztimeYear, mapStr);
	}

	private float count(Integer year, Integer fztimeYear, Map<String, String> mapStr) {
		float value = -1f;
		switch (year - fztimeYear) {
		case 0:
			value = valueOfFloat(mapStr.get("sqoneyear"));
			break;
		case 1:
			value = valueOfFloat(mapStr.get("sqtwoyear"));
			break;
		case 2:
			value = valueOfFloat(mapStr.get("sqthreeyear"));
			break;
		case 3:
			value = valueOfFloat(mapStr.get("sqfouryear"));
			break;
		case 4:
			value = valueOfFloat(mapStr.get("sqfiveyear"));
			break;
		}
		return value;
	}

	// 取值校验
	private float valueOfFloat(String value) {
		return StringUtils.isNotBlank(value) && !value.contains("/") ? Float.valueOf(value) : -1f;
	}

	@Override
	public Map<String, Float> airCountOne(SearchDto searchDto) {
		Map<String, Float> countData = countUtil(searchDto, 1, true);
		return countData;
	}

	@Override
	public Map<String, Float> airCountTwo(SearchDto searchDto) {
		Map<String, Float> countData = countUtil(searchDto, 2, true);
		return countData;
	}

	@Override
	public Map<String, Float> airCountThr(SearchDto searchDto) {
		Map<String, Float> countData = countUtil(searchDto, 3, true);
		return countData;
	}

	@Override
	public TableResultDto<Map<String, Object>> airCountOneTable(SearchDto searchDto, Long draw) {
		return countTableUtil(searchDto, 1, true, draw);
	}

	@Override
	public TableResultDto<Map<String, Object>> airCountTwoTable(SearchDto searchDto, Long draw) {
		return countTableUtil(searchDto, 2, true, draw);
	}

	@Override
	public TableResultDto<Map<String, Object>> airCountThrTable(SearchDto searchDto, Long draw) {
		return countTableUtil(searchDto, 3, true, draw);
	}

	// TODO 水排放口统计
	@Override
	public TableResultDto<Map<String, Object>> waterCountOneTable(SearchDto searchDto, Long draw) {
		return countTableUtil(searchDto, 1, false, draw);
	}

	@Override
	public Map<String, Float> waterCountOne(SearchDto searchDto) {
		return countUtil(searchDto, 1, false);
	}

	@Override
	public Map<String, Float> waterCountTwo(SearchDto searchDto) {
		return countUtil(searchDto, 2, false);
	}

	@Override
	public TableResultDto<Map<String, Object>> waterCountTwoTable(SearchDto searchDto, Long draw) {
		return countTableUtil(searchDto, 2, false, draw);
	}

	@Override
	public TableResultDto<Map<String, Object>> waterCountThrTable(SearchDto searchDto, Long draw) {
		return countTableUtil(searchDto, 3, false, draw);
	}

	@Override
	public Map<String, Float> waterCounThr(SearchDto searchDto) {
		return countUtil(searchDto, 3, false);
	}

	@Override
	public Map<String, Float> waterCountFour(SearchDto searchDto) {
		return countUtil(searchDto, 4, false);
	}

	@Override
	public TableResultDto<Map<String, Object>> waterCountFourTable(SearchDto searchDto, Long draw) {
		return countTableUtil(searchDto, 4, false, draw);
	}

	QWaterDrainBaseInfoOne qWaterDrainBaseInfoOne = QWaterDrainBaseInfoOne.waterDrainBaseInfoOne;
	QWaterDrainBaseInfoTwo qWaterDrainBaseInfoTwo = QWaterDrainBaseInfoTwo.waterDrainBaseInfoTwo;
	QWaterDrainBaseInfoThr qWaterDrainBaseInfoThr = QWaterDrainBaseInfoThr.waterDrainBaseInfoThr;
	QAirPollution qAirPollution = QAirPollution.airPollution;
	QDrainBaseInfo qDrainBaseInfo = QDrainBaseInfo.drainBaseInfo;

	@Override
	public List<Map<String, Object>> DrainCountMap(SearchDto searchDto, EDrainCountType eGroup) {
		if (EDrainCountType.waterCount == eGroup) {
			return waterDrainCountMap(searchDto);
		} else {
			return airDrainCountMap(searchDto);
		}
	}

	private List<Map<String, Object>> airDrainCountMap(SearchDto searchDto) {
		List<Map<String, Object>> resultMap = new ArrayList<Map<String, Object>>();
		JPAQuery<Tuple> query = new JPAQuery<>(em);
		query.select(qPwBaseInfo.dataid,qPwBaseInfo.hyid, qBaseInfo.code_region, qBaseInfo.wsystemname, qDrainBaseInfo.latitude,
				qDrainBaseInfo.longitude, qDrainBaseInfo.drainname, qDrainBaseInfo.xkdraincode, qDrainBaseInfo.wrwname,
				qDrainBaseInfo.exhaustheight, qDrainBaseInfo.exhaustbore, qPwBaseInfo.devcompany,
				qPwBaseInfo.regaddress);
		query.from(qLatestData).leftJoin(qDrainBaseInfo).on(qLatestData.dataid.eq(qDrainBaseInfo.dataid));
		query.leftJoin(qPwBaseInfo).on(qPwBaseInfo.dataid.eq(qDrainBaseInfo.dataid));
		query.leftJoin(qBaseInfo).on(qBaseInfo.enterid.eq(qPwBaseInfo.enterid));

		DrainCountMapWhere(searchDto, query);
		List<Tuple> result = query.fetch();
		for (Tuple row : result) {
			HashMap<String, Object> dataMap = new HashMap<String, Object>();
			dataMap.put("hyid", row.get(qPwBaseInfo.hyid));
			dataMap.put("dataid", row.get(qPwBaseInfo.dataid));
			dataMap.put("code_region", row.get(qBaseInfo.code_region));
			dataMap.put("wsystemname", row.get(qBaseInfo.wsystemname));
			dataMap.put("lat", row.get(qDrainBaseInfo.latitude));
			dataMap.put("long", row.get(qDrainBaseInfo.longitude));
			dataMap.put("drainname", row.get(qDrainBaseInfo.drainname));
			dataMap.put("xkdraincode", row.get(qDrainBaseInfo.xkdraincode));
			dataMap.put("wrwname", row.get(qDrainBaseInfo.wrwname));
			dataMap.put("exhaustheight", row.get(qDrainBaseInfo.exhaustheight));
			dataMap.put("exhaustbore", row.get(qDrainBaseInfo.exhaustbore));
			dataMap.put("devcompany", row.get(qPwBaseInfo.devcompany));
			// dataMap.put("othercontent",
			// row.get(qDrainBaseInfo.othercontent));
			dataMap.put("regaddress", row.get(qPwBaseInfo.regaddress));
			dataMap.put("qthyname", row.get(qPwBaseInfo.qthyname));
			resultMap.add(dataMap);
		}
		return resultMap;
	}

	private List<Map<String, Object>> waterDrainCountMap(SearchDto searchDto) {
		List<Map<String, Object>> waterOne = DrainCountMapQuery(searchDto, 1);
		List<Map<String, Object>> waterTwo = DrainCountMapQuery(searchDto, 2);
		List<Map<String, Object>> waterThr = DrainCountMapQuery(searchDto, 3);
		waterOne.addAll(waterTwo);
		waterOne.addAll(waterThr);
		return waterOne;
	}

	private List<Map<String, Object>> DrainCountMapQuery(SearchDto searchDto, int num) {
		List<Map<String, Object>> resultMap = new ArrayList<Map<String, Object>>();
		JPAQuery<Tuple> query = new JPAQuery<>(em);
		// query.select(qPwBaseInfo.hyid, qBaseInfo.code_region,
		// qBaseInfo.wsystemname);
		switch (num) {
		case 1:
			query.select(qPwBaseInfo.dataid,qPwBaseInfo.hyid, qBaseInfo.code_region, qBaseInfo.wsystemname,
					qWaterDrainBaseInfoOne.latitude, qWaterDrainBaseInfoOne.longitude,
					qWaterDrainBaseInfoOne.xkdraincode, qWaterDrainBaseInfoOne.drainname,
					qWaterDrainBaseInfoOne.pfqxname, qWaterDrainBaseInfoOne.pffsname, qPwBaseInfo.devcompany,
					qPwBaseInfo.regaddress, qWaterDrainBaseInfoOne.sewagename, qWaterDrainBaseInfoOne.functionname);
			query.from(qLatestData).leftJoin(qWaterDrainBaseInfoOne)
					.on(qLatestData.dataid.eq(qWaterDrainBaseInfoOne.dataid));
			query.leftJoin(qPwBaseInfo).on(qPwBaseInfo.dataid.eq(qWaterDrainBaseInfoOne.dataid));
			break;
		case 2:
			query.select(qPwBaseInfo.dataid,qPwBaseInfo.hyid, qBaseInfo.code_region, qBaseInfo.wsystemname,
					qWaterDrainBaseInfoTwo.latitude, qWaterDrainBaseInfoTwo.longitude,
					qWaterDrainBaseInfoTwo.xkdraincode, qWaterDrainBaseInfoTwo.drainname,
					qWaterDrainBaseInfoTwo.pfqxname, qWaterDrainBaseInfoTwo.pffsname, qPwBaseInfo.devcompany,
					qPwBaseInfo.regaddress, qWaterDrainBaseInfoTwo.sewagename, qWaterDrainBaseInfoTwo.functionname);
			query.from(qLatestData).leftJoin(qWaterDrainBaseInfoTwo)
					.on(qLatestData.dataid.eq(qWaterDrainBaseInfoTwo.dataid));
			query.leftJoin(qPwBaseInfo).on(qPwBaseInfo.dataid.eq(qWaterDrainBaseInfoTwo.dataid));
			break;
		case 3:
			query.select(qPwBaseInfo.dataid,qPwBaseInfo.hyid, qBaseInfo.code_region, qBaseInfo.wsystemname,
					qWaterDrainBaseInfoThr.latitude, qWaterDrainBaseInfoThr.longitude,
					qWaterDrainBaseInfoThr.xkdraincode, qWaterDrainBaseInfoThr.drainname,
					qWaterDrainBaseInfoThr.pfqxname, qWaterDrainBaseInfoThr.pffsname, qPwBaseInfo.devcompany,
					qPwBaseInfo.regaddress, qWaterDrainBaseInfoThr.sewagename, qWaterDrainBaseInfoThr.functionname);
			query.from(qLatestData).leftJoin(qWaterDrainBaseInfoThr)
					.on(qLatestData.dataid.eq(qWaterDrainBaseInfoThr.dataid));
			query.leftJoin(qPwBaseInfo).on(qPwBaseInfo.dataid.eq(qWaterDrainBaseInfoThr.dataid));
			break;
		}
		query.leftJoin(qBaseInfo).on(qBaseInfo.enterid.eq(qPwBaseInfo.enterid));

		DrainCountMapWhere(searchDto, query);

		List<Tuple> result = query.fetch();

		for (Tuple row : result) {
			HashMap<String, Object> dataMap = new HashMap<String, Object>();
			dataMap.put("hyid", row.get(qPwBaseInfo.hyid));
			dataMap.put("code_region", row.get(qBaseInfo.code_region));
			dataMap.put("wsystemname", row.get(qBaseInfo.wsystemname));
			dataMap.put("regaddress", row.get(qPwBaseInfo.regaddress));
			dataMap.put("devcompany", row.get(qPwBaseInfo.devcompany));
			dataMap.put("devcompany", row.get(qPwBaseInfo.devcompany));
			dataMap.put("dataid", row.get(qPwBaseInfo.dataid));
			switch (num) {
			case 1:
				dataMap.put("lat", row.get(qWaterDrainBaseInfoOne.latitude));
				dataMap.put("long", row.get(qWaterDrainBaseInfoOne.longitude));
				dataMap.put("xkdraincode", row.get(qWaterDrainBaseInfoOne.xkdraincode));
				dataMap.put("drainname", row.get(qWaterDrainBaseInfoOne.drainname));
				dataMap.put("pfqxname", row.get(qWaterDrainBaseInfoOne.pfqxname));
				dataMap.put("pffsname", row.get(qWaterDrainBaseInfoOne.pffsname));
				dataMap.put("sewagename", row.get(qWaterDrainBaseInfoOne.sewagename));
				dataMap.put("functionname", row.get(qWaterDrainBaseInfoOne.functionname));
				// dataMap.put("remarks",
				// row.get(qWaterDrainBaseInfoOne.remarks));
				break;
			case 2:
				dataMap.put("lat", row.get(qWaterDrainBaseInfoTwo.latitude));
				dataMap.put("long", row.get(qWaterDrainBaseInfoTwo.longitude));
				dataMap.put("xkdraincode", row.get(qWaterDrainBaseInfoTwo.xkdraincode));
				dataMap.put("drainname", row.get(qWaterDrainBaseInfoTwo.drainname));
				dataMap.put("pfqxname", row.get(qWaterDrainBaseInfoTwo.pfqxname));
				dataMap.put("pffsname", row.get(qWaterDrainBaseInfoTwo.pffsname));
				dataMap.put("sewagename", row.get(qWaterDrainBaseInfoTwo.sewagename));
				dataMap.put("functionname", row.get(qWaterDrainBaseInfoTwo.functionname));
				// dataMap.put("remarks",
				// row.get(qWaterDrainBaseInfoTwo.remarks));
				break;
			case 3:
				dataMap.put("lat", row.get(qWaterDrainBaseInfoThr.latitude));
				dataMap.put("long", row.get(qWaterDrainBaseInfoThr.longitude));
				dataMap.put("xkdraincode", row.get(qWaterDrainBaseInfoThr.xkdraincode));
				dataMap.put("drainname", row.get(qWaterDrainBaseInfoThr.drainname));
				dataMap.put("pfqxname", row.get(qWaterDrainBaseInfoThr.pfqxname));
				dataMap.put("pffsname", row.get(qWaterDrainBaseInfoThr.pffsname));
				dataMap.put("sewagename", row.get(qWaterDrainBaseInfoThr.sewagename));
				dataMap.put("functionname", row.get(qWaterDrainBaseInfoThr.functionname));
				// dataMap.put("remarks",
				// row.get(qWaterDrainBaseInfoThr.remarks));
				break;
			default:
				break;
			}
			resultMap.add(dataMap);

		}
		return resultMap;

	}

	private void DrainCountMapWhere(SearchDto searchDto, JPAQuery<Tuple> query) {
		if (StringUtils.isNotBlank(searchDto.getCodeRegion())) {
			query.where(qBaseInfo.code_region.eq(searchDto.getCodeRegion()));
		}
		if (StringUtils.isNotBlank(searchDto.getHyid())) {
			query.where(qPwBaseInfo.hyid.eq(searchDto.getHyid()));
		}
		if (null != searchDto.getHyids() && searchDto.getHyids().length > 0) {
			query.where(qPwBaseInfo.hyid.in(searchDto.getHyids()));
		}
		if (StringUtils.isNotBlank(searchDto.getCodeWsystem())) {
			query.where(qBaseInfo.cod_wsystem.eq(searchDto.getCodeWsystem()));
		}
		if (StringUtils.isNotBlank(searchDto.getDevcompany())) {
			query.where(qPwBaseInfo.devcompany.contains(searchDto.getDevcompany()));
		}
	}
}
